package scheduler;

import DB_Manage.DatabaseManager;
import Integrity.DataInt_ErrorChecking_Interface;
import Integrity.Result;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import javaapplication12.Main;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;

import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

public class ScheduledItem {
	static Logger logger = Logger.getLogger(Main.class);

	String userId;
	String billingSiteRef;
	Date lastRunDate;
	Date lastStatementDate;
	Double lastStatementTotal;

	private Date nextScheduledRun = new Date();
	static DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	static DateFormat sfm = new SimpleDateFormat("MMM-dd HH:mm:ss");

	public ScheduledItem(String userId, String billingSiteRef, Date lastRunDate,
			Date lastStatementDate, Double lastStatementTotal) {
		this.userId = userId;
		this.billingSiteRef = billingSiteRef;
		this.lastRunDate = lastRunDate;
		this.lastStatementDate = lastStatementDate;
		this.lastStatementTotal = lastStatementTotal;
		this.nextScheduledRun = this.calculateNextScheduledRun(this.lastRunDate, this.billingSiteRef);
	}

	public ScheduledItem()
	{
		//Null constructor
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public String getBillingSiteRef() {
		return billingSiteRef;
	}

	public void setBillingSiteRef(String billingSiteRef) {
		this.billingSiteRef = billingSiteRef;
	}

	public Date getLastRunDate() {
		return lastRunDate;
	}

	public void setLastRunDate(Date lastRunDate) {
		this.lastRunDate = lastRunDate;
	}

	public Date getLastStatementDate() {
		return lastStatementDate;
	}

	public void setLastStatementDate(Date lastStatementDate) {
		this.lastStatementDate = lastStatementDate;
	}

	public Double getLastStatementTotal() {
		return lastStatementTotal;
	}

	public void setLastStatementTotal(Double lastStatementTotal) {
		this.lastStatementTotal = lastStatementTotal;
	}

	public Date getNextScheduledRun() {
		return nextScheduledRun;
	}

	public void setNextScheduledRun(Date nextScheduledRun) {
		this.nextScheduledRun = nextScheduledRun;
	}

	public static DateFormat getDfm() {
		return dfm;
	}

	public static void setDfm(DateFormat dfm) {
		ScheduledItem.dfm = dfm;
	}

	public static DateFormat getSfm() {
		return sfm;
	}

	public static void setSfm(DateFormat sfm) {
		ScheduledItem.sfm = sfm;
	}





	/*
	// Retrieve the scheduled job from the persistent store 
	public void buildScheduledItem(int x) throws ParseException {

		switch (x) { 
		case 0 :
			user.buildUser("Oweson");
			this.user = user;
			this.userId = this.user.userId;
			this.billingSite = BillingSite.buildBillingSite(1);
			this.billingSiteRef = this.billingSite.billingSiteRef;
			this.lastRunDate = dfm.parse("2010-05-03 10:15:00");
			this.lastStatementDate = dfm.parse("2010-04-30 00:00:00");
			this.lastStatementTotal = 123.45;
			this.nextScheduledRun = this.calculateNextScheduledRun(this.lastRunDate, this.billingSite.getBillingCycle(), this.billingSite.getLeadTime());
			break;
		case 1 :
			user.buildUser("John");
			this.user = user;
			this.userId = this.user.userId;
			this.billingSite = billingSite.buildBillingSite(2);
			this.billingSiteRef = this.billingSite.billingSiteRef;
			this.lastRunDate = (Date) dfm.parse("2010-05-28 19:15:00");
			this.lastStatementDate = (Date) dfm.parse("2010-05-01 00:00:00");
			this.lastStatementTotal = 654.32;
			this.nextScheduledRun = this.calculateNextScheduledRun(this.lastRunDate, this.billingSite.getBillingCycle(), this.billingSite.getLeadTime());
			break;
		}
	}
	 */	


	public static Date today() {
		Calendar cal = Calendar.getInstance();
		return cal.getTime();
	}

	private Date calculateNextScheduledRun(Date lastRunDate, String billingSiteRef) {
		int cycle = 0;
		int lead  = 0;
		int daysToAdd;
		Date newDate;
		BillingSite billingSite = new BillingSite();

		//billingSite = billingSite.retrBillingSite(billingSiteRef);
                
		//-billingSite = billingSite.buildBillingSite(billingSiteRef);
		//-cycle = billingSite.getBillingCycle();
		//-lead = billingSite.getLeadTime();

		/*System.out.println("calculateNextScheduledRun");
		System.out.println("\tlastRun: " + dfm.format(lastRun ));
		System.out.println("\tcycle: " + cycle);
		System.out.println("\tcycle: " + lead);
		System.out.println("\tdaysToAdd: " + daysToAdd);
		System.out.println("\tNow: " +  Job.now());
		 */

		daysToAdd = cycle - lead;
		java.util.Date nextScheduledRun;
		Calendar cal  = Calendar.getInstance();
		cal.setTime(lastRunDate);
		cal.add(Calendar.DATE, daysToAdd);
		newDate = cal.getTime();

		//final String dfn = "yyyy-MM-dd-HHmmss";
		//System.out.println("\tNewDate: " + dfm.format(newDate));

		//       System.out.println("\tNextScheduledRun: " + dfm.format(nextScheduledRun) + "\n----\n");
		return newDate;
	}

/*
	public Date calculateNextScheduledRun(Date lastRun, int cycle, int lead) {
		int daysToAdd = cycle - lead;
		Date newDate;

		System.out.println("calculateNextScheduledRun");
		System.out.println("\tlastRun: " + dfm.format(lastRun ));
		System.out.println("\tcycle: " + cycle);
		System.out.println("\tcycle: " + lead);
		System.out.println("\tdaysToAdd: " + daysToAdd);
		System.out.println("\tNow: " +  Job.now());
		 
		java.util.Date nextScheduledRun;
		Calendar cal  = Calendar.getInstance();
		cal.setTime(lastRun);
		cal.add(Calendar.DATE, daysToAdd);
		newDate = cal.getTime();

		//final String dfn = "yyyy-MM-dd-HHmmss";
		//System.out.println("\tNewDate: " + dfm.format(newDate));

		//       System.out.println("\tNextScheduledRun: " + dfm.format(nextScheduledRun) + "\n----\n");
		return newDate;
	}
*/
	public void print(boolean all) {
		System.out.println("Scheduled Item [" + this + "]");
		System.out.println("userId:            " + this.userId);
		System.out.println("billingSiteRef:    " + this.billingSiteRef);;
		System.out.println("lastStatementDate: " + dfm.format(this.lastStatementDate));
		System.out.println("lastRunDate:       " + dfm.format(this.lastRunDate));
		System.out.println("nextScheduledRun:  " + dfm.format( this.nextScheduledRun));
		System.out.println( "---- End of Scheduled Item  -----\n");
	}
	
	public void print() {
		print(false);
	}


	public void printScheduledTime() {
		System.out.println(
				"nextScheduledRun [" + sfm.format( this.nextScheduledRun) + "]"
				+ "lastRunDate [" + sfm.format(this.lastRunDate) + "] " 
				+ "userId [" + this.userId + "] "
				+ "billingSiteRef [" + this.billingSiteRef + "] " 
		);

	}

	// Work out the billing site template file name
	private String getFiletype(String billingSiteRef) {
		String filename = null;
		SiteType st = null;
		BillingSite bs = new BillingSite();
		
		logger.debug("getFileType billingSiteRef[" + billingSiteRef + "]");
		bs = bs.retrBillingSite(billingSiteRef);
		st = bs.getSiteType();
		logger.debug("billingSiteRef SiteType[" + st + "]");
		if (st.equals(SiteType.MUNICIPALITY)) {
			filename = "municipal.xml";
		} else if (st.equals(SiteType.TELKOM)) {
			filename = "telco.xml";
		}
		else
			filename = "credit_card.xml";
		
		logger.debug("getFileType filename[" + filename + "]");
		return filename;
	}

	public void executeTask() throws XPathExpressionException, ParserConfigurationException, SAXException, IOException, Exception {
		String parm = new String();
		Job job = new Job();

		//		Calendar cal  = Calendar.getInstance(); System.out.println(dfm.format(cal.getTime()) +" Execute Task " + this.billingSiteRef + " for " + this.userId);

		String srcFilename = getFiletype(this.billingSiteRef);
		
		// Load the job to be run.
		logger.debug("Retrieving Job for [" + this.userId + "] Site [" + this.billingSiteRef+ "]");
		job.retrieveJob(this.userId, this.billingSiteRef);
		//execute scraper
		// build arguments
		parm = "Scraper ";
		parm += job.scrapeFilename + " ";

		// Get the encrypted pairs.
		for (int j=0; j<5; j++)
		{
			parm += job.credentialPairs[j].getPair();
		}

		// Get the identifier pairs.
		for (int j=0; j<5; j++)
		{
			parm += job.identifierPairs[j].getPair();
		}
		logger.info("Executing [" + parm + "]");

		// invoke scraper
		//Call: scraper [scriptname] [output_filename] \
		//              [username]/[password] \
		//              [credential_text2]/[credential_value2] ... [credential_text5]/[credential_value5] \
		//              [identifier_text1]/[identifier_value1] ... [identifier_text5]/[identifier_value5]
		// This command emulates the scarper, and copies the data file with the expected file name
		logger.debug("Data Filename [" + job.scrapeFilename + "]");
		
		// *** Run the copy on Linux ***//
		//String[] cmd = {"/bin/sh", "-c", "cp "+ srcFilename + " " + job.scrapeFilename};
		//Runtime.getRuntime().exec(cmd);
		// *** End of run on Linux *** //

		/* *** Windows version of the run command. ***/
                
                if(this.userId.compareTo("UID003")==0)
                {
                    srcFilename = "inval_cred.xml";
                }
		try {
			String line = "C:\\Documents and Settings\\user\\Desktop\\Wits 2010\\7045\\Main Project\\Test\\JavaApplication12\\";
                        String source = line+srcFilename;
                        String dest = line+job.scrapeFilename;
			//Process p = Runtime.getRuntime().exec("test.cmd");
                        System.out.println("***** "+line+job.scrapeFilename + " *****");
                        System.out.println("***** "+line+srcFilename + " *****");
                        String[] command = { "cmd.exe", "/c", "copy", source, dest };
			//Process p = Runtime.getRuntime().exec("cmd.exe /c copy "+ line+srcFilename + " " + line+job.scrapeFilename);
                        Process p = Runtime.getRuntime().exec(command);
			p.waitFor();
			System.out.println(p.exitValue());
		}
		catch (Exception err) {
			err.printStackTrace();
		}
		/*** Windows Run Command ***/
		
		//invoke loadresult
	     Thread.sleep(2000); // Pause for file to be created.
	     
         DataInt_ErrorChecking_Interface result = new DataInt_ErrorChecking_Interface(userId, billingSiteRef, job.scrapeFilename);
		//data_Int_Error_checking_Interface(this.userId, job.scrapeFilename);

		//recalculate next run date
		this.calculateNextScheduledRun(this.lastRunDate, this.billingSiteRef);
          //System.out.println(result.createResult().toString());
          DatabaseManager dbm = new DatabaseManager();
          dbm.storeResult(result.createResult());

	}

}